package org.activiti.designer.eclipse.editor;
import java.io.File;
import org.activiti.designer.eclipse.bpmnimport.ImportBpmnUtil;
import org.activiti.designer.eclipse.common.ActivitiBPMNDiagramConstants;
import org.activiti.designer.eclipse.editor.sync.DiagramUpdater;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.draw2d.IFigure;
import org.eclipse.emf.common.util.URI;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.ui.editor.DiagramEditorFactory;
import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
/**
* @author Yvo Swillens
* @since 0.6.1
* @version 1
*
*/
public class ActivitiMultiPageEditor extends MultiPageEditorPart implements IResourceChangeListener {
private static final String DIAGRAM_PANE_TILE = "Diagram";
private static final String XML_PANE_TITLE = "BPMN2.0";
/** The diagram editor used in page 0. */
private ActivitiDiagramEditor diagramEditor;
/** The XML editor used in page 1. */
private StructuredTextEditor bpmnEditor;
private IFile associatedBPMN2File;
/**
* Creates a multi-page editor example.
*/
public ActivitiMultiPageEditor() {
super();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
private void createDiagramPage() {
try {
diagramEditor = new ActivitiDiagramEditor();
int index = addPage(diagramEditor, getEditorInput());
setPageText(index, ActivitiMultiPageEditor.DIAGRAM_PANE_TILE);
GraphicalViewer graphicalViewer = (GraphicalViewer) diagramEditor.getAdapter(GraphicalViewer.class);
if (graphicalViewer != null && graphicalViewer.getEditPartRegistry() != null) {
ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) graphicalViewer.getEditPartRegistry().get(LayerManager.ID);
IFigure gridFigure = ((LayerManager) rootEditPart).getLayer(LayerConstants.GRID_LAYER);
gridFigure.setVisible(false);
}
} catch (PartInitException e) {
ErrorDialog.openError(getSite().getShell(), "Error creating nested Activiti Diagram editor", null, e.getStatus());
}
}
private void createBPMN2Page() {
try {
bpmnEditor = new StructuredTextEditor();
int index = addPage(bpmnEditor, getBPMN2EditorInput());
setPageText(index, ActivitiMultiPageEditor.XML_PANE_TITLE);
} catch (PartInitException e) {
ErrorDialog.openError(getSite().getShell(), "Error creating nested Activiti BPMN2.0 editor", null, e.getStatus());
}
}
/**
* Creates the pages of the multi-page editor.
*/
protected void createPages() {
createDiagramPage();
createBPMN2Page();
}
public void dispose() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
super.dispose();
}
public void doSave(IProgressMonitor monitor) {
int activePage = getActivePage();
if (activePage == 0) {
getEditor(0).doSave(monitor);
} else if (activePage == 1) {
// Save BPMN editor contents
getEditor(1).doSave(monitor);
// sync Activiti Diagram
DiagramEditorInput diagramEditorInput = (DiagramEditorInput) getEditor(0).getEditorInput();
Diagram diagram = diagramEditorInput.getDiagram();
FileEditorInput bpmn2EditorInput = (FileEditorInput) getEditor(1).getEditorInput();
IStorage bpmnStorage = bpmn2EditorInput.getStorage();
//DiagramUpdater.syncDiagram(diagramEditor, diagram, bpmnStorage);
// Save BPMN editor contents
getEditor(0).doSave(monitor);
}
}
public void doSaveAs() {
int activePage = getActivePage();
if (activePage == 0) {
IEditorPart editor = getEditor(0);
editor.doSaveAs();
setPageText(0, editor.getTitle());
setInput(editor.getEditorInput());
} else if (activePage == 1) {
IEditorPart editor = getEditor(1);
editor.doSaveAs();
setPageText(1, editor.getTitle());
setInput(editor.getEditorInput());
}
}
public void gotoMarker(IMarker marker) {
setActivePage(0);
IDE.gotoMarker(getEditor(0), marker);
}
public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
if (!(editorInput instanceof IFileEditorInput) && !(editorInput instanceof DiagramEditorInput))
throw new PartInitException("Invalid Input: Must be Activiti Diagram or BPMN2.0 XML");
// checks if the editor was opened with non Diagram file
if (editorInput instanceof IFileEditorInput) {
if (isBPM2FileType((IFileEditorInput) editorInput)) {
associatedBPMN2File = ((IFileEditorInput) editorInput).getFile();
final IFile diagramFile = getAssociatedDiagramIFile(associatedBPMN2File);
if(diagramFile.exists() == false) {
String bpmnFile = associatedBPMN2File.getRawLocation().toFile().getAbsolutePath();
String processName = bpmnFile.substring(bpmnFile.lastIndexOf(File.separator) + 1);
processName = processName.replace(".xml", "");
processName = processName.replace(".bpmn20", "");
ImportBpmnUtil.createDiagram(processName, bpmnFile,
associatedBPMN2File.getProject(), associatedBPMN2File.getParent());
}
final IEditorInput diagramFileEditorInput = new FileEditorInput(diagramFile);
// creates DiagramEditorInput from FileEditorInput
editorInput = new DiagramEditorFactory().createEditorInput(diagramFileEditorInput);
}
}
super.init(site, editorInput);
}
public boolean isSaveAsAllowed() {
return true;
}
public ActivitiDiagramEditor getActivitiDiagramEditor() {
IEditorPart editor = getEditor(0);
return (ActivitiDiagramEditor) editor;
}
/**
* Closes all project files on project close.
*/
public void resourceChanged(final IResourceChangeEvent event) {
if (event.getType() == IResourceChangeEvent.PRE_CLOSE) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages();
for (int i = 0; i < pages.length; i++) {
if (((FileEditorInput) bpmnEditor.getEditorInput()).getFile().getProject().equals(event.getResource())) {
IEditorPart editorPart = pages[i].findEditor(bpmnEditor.getEditorInput());
pages[i].closeEditor(editorPart, true);
}
}
}
});
}
}
/**
* Reloads contents of BPMN2 pane when selected
*/
protected void pageChange(int newPageIndex) {
super.pageChange(newPageIndex);
if (newPageIndex == 1) {
bpmnEditor.setInput(getBPMN2EditorInput());
bpmnEditor.doRevertToSaved();
}
}
private IFile getAssociatedBPMN2IFile() {
URI uri = getAssociatedBPMN2URI();
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IFile bpmn20File = workspace.getRoot().getFile(new Path(uri.toPlatformString(true)));
return bpmn20File;
}
private URI getAssociatedBPMN2URI() {
final Diagram diagram = ((DiagramEditorInput) diagramEditor.getEditorInput()).getDiagram();
final URI originalURI = diagram.eResource().getURI();
final URI parentURI = originalURI.trimSegments(1);
final String REGEX_FILENAME = "\\$originalFile";
String finalSegment = "$originalFile" + ".bpmn20.xml";
finalSegment = finalSegment.replaceAll(REGEX_FILENAME, originalURI.lastSegment().substring(
0, originalURI.lastSegment().indexOf(".")));
return parentURI.appendSegment(finalSegment);
}
private IFile getAssociatedDiagramIFile(final IFile bpmnFile) {
IPath path = getAssociatedDiagramURI(bpmnFile);
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IFile diagramFile = workspace.getRoot().getFile(path);
return diagramFile;
}
private IPath getAssociatedDiagramURI(final IFile bpmnFile) {
final IPath originalPath = bpmnFile.getFullPath();
final IPath parentPath = originalPath.removeLastSegments(1);
String finalSegment = originalPath.lastSegment();
finalSegment = finalSegment.replace(".bpmn20.xml", ".activiti");
final IPath returnPath = parentPath.append(new Path(finalSegment));
return returnPath;
}
private IFileEditorInput getBPMN2EditorInput() {
associatedBPMN2File = getAssociatedBPMN2IFile();
return new FileEditorInput(associatedBPMN2File);
}
private boolean isBPM2FileType(final IFileEditorInput editorInput) {
boolean isBPMN2File = false;
IFile file = editorInput.getFile();
try {
IContentDescription desc = file.getContentDescription();
if (desc != null) {
IContentType type = desc.getContentType();
if (ActivitiBPMNDiagramConstants.BPMN2_CONTENTTYPE_ID.equals(type.getId())) {
isBPMN2File = true;
}
}
} catch (CoreException e) {
e.printStackTrace();
return isBPMN2File;
}
return isBPMN2File;
}
}